package com.wang.tool.valve.strategy;

import com.alibaba.fastjson.JSONPath;
import com.wang.tool.util.CommonUtil;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author shaopeng
 * @date 2023/5/7
 */
public class JsonpathValve extends AbsValve {
    private static final long serialVersionUID = 4689210351593519461L;

    /**
     * 策略名
     */
    public static final String STRATEGY = "jsonpath";

    /**
     * 参数源
     */
    private List<String> sources;

    /**
     * 白名单
     */
    private Set<String> whites;



    private transient List<JSONPath> compiledSources = new ArrayList<>();
    @Override
    public void prepare() throws IllegalArgumentException {
        if (CommonUtil.isEmpty(sources) || CommonUtil.isEmpty(whites)) {
            compiledSources = new ArrayList<>();
            return;
        }
        compiledSources = sources
                .stream()
                .map(s -> {
                    JSONPath compile = JSONPath.compile(s);
                    compile.eval(new Object());
                    return compile;
                }).collect(Collectors.toList());
    }

    @Override
    protected boolean internalIsPass(Object param) throws Exception {
        for (JSONPath source : compiledSources) {
            Object val = source.eval(param);
            if (val == null) {
                continue;
            }
            //集合
            if (val instanceof Collection) {
                if(((Collection<?>) val).stream()
                        .anyMatch(s -> whites.contains(String.valueOf(s)))){
                    return true;
                }
            }else if(whites.contains(val.toString())){
                return true;
            }
        }
        return false;
    }


    public List<String> getSources() {
        return sources;
    }

    public void setSources(List<String> sources) {
        this.sources = sources;
    }

    public Set<String> getWhites() {
        return whites;
    }

    public void setWhites(Set<String> whites) {
        this.whites = whites;
    }

    @Override
    public String toString() {
        return "JsonpathValve{" +
                "sources=" + sources +
                ", whites=" + whites +
                '}';
    }
}
